﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace PKSpeed
{
    /// <summary>
    /// 用户相关命令
    /// </summary>
    class UserOperation
    {
        private static string key = "xiaokang";   //md5加密密钥


        /// <summary>
        /// 用户登录
        /// </summary>
        /// <returns>是否登录成功</returns>
        public static bool Login()
        {
            Console.Write("Username:");
            string userName = Console.ReadLine();
            if (userName == "guest")   //判断是否为guest
            {
                Console.WriteLine("Login successfully! Welcome to the SeedCup shell!");
                Program.CurrentCommand.CurrentUser = "guest";
                return true;
            }
            else
            {
                User user = UserConfiguration.GetUser(userName);
                if (user == null)     //判断用户是否存在
                {
                    Console.WriteLine("Error:no user named {0}!", userName);
                    return false;
                }
                else
                {
                    Console.Write("Password:");
                    string password = GetStandardPassword(); 
                    string encryptpassword = Encrypt.EncryptString(password, key); //将输入的密码加密与原密码比较
                    if (user.PassWord != encryptpassword)//密码不匹配
                    {
                        Console.WriteLine("Error:wrong passsword!");
                        return false;
                    }
                    else
                    {
                        Program.CurrentCommand.CurrentUser = userName;//密码匹配
                        Console.WriteLine("Login successfully! Welcome to the SeedCup shell!");
                        return true;
                    }
                }
            }
        }

        /// <summary>
        /// 用户添加
        /// </summary>
        /// <param name="commandArg"></param>
        /// <param name="args"></param>
        /// <param name="outFileName"></param>
        /// <param name="grepArg"></param>
        /// <returns>用户添加是否成功</returns>
        public static bool UserAdd(String commandArg, List<String> args, String outFileName, List<String> grepArg)
        {
            //参数考察
            if ((!String.IsNullOrEmpty(commandArg)) || (!String.IsNullOrEmpty(outFileName))|| grepArg.Count != 0 || args.Count != 1) 
            {
                Console.WriteLine("Error:参数错误!");
                return false;
            }
            string userName = args[0];
            //判断username是否全由字母和数字组成
            for (int i = 0; i < userName.Length; i++)
            {
                if (!((userName[i] <= 'Z' && userName[i] >= 'A')
                || (userName[i] <= 'z' && userName[i] >= 'a')
                || (userName[i] <= '9' && userName[i] >= '0')))
                {
                    Console.WriteLine("Error:用户名只能包含字母和数字!");
                    return false;
                }
            }
            //username长度
            if (userName.Length < 1 || userName.Length > 10)
            {
                Console.WriteLine("Error:the length of username should be 1~10");
                return false;
            }
            User user = UserConfiguration.GetUser(userName);
            if (user != null ||userName == "guest") //不能添加guest的同名用户或者查不到用户
            {
                Console.WriteLine("Error:user of {0} exists!", userName);
                return false;
            }
            Console.Write("Password:");
            string password1 = GetStandardPassword();
            //判断password1是否由字母和数字组成
            for (int i = 0; i < password1.Length; i++)
            {
                if (!((password1[i] <= 'Z' && password1[i] >= 'A')
                || (password1[i] <= 'z' && password1[i] >= 'a')
                || (password1[i] <= '9' && password1[i] >= '0')))
                {
                    Console.WriteLine("Error:密码只能包含字母和数字!");
                    return false;
                }
            }
            //判断password1长度是否符合标准
            if (password1.Length < 6 || password1.Length > 20)
            {
                Console.WriteLine("Error:the length of password should be 6~20");
                return false;
            }
            Console.Write("Password again:");
            string password2 = GetStandardPassword();
            //同上判断
            for (int i = 0; i < password2.Length; i++)
            {
                if (!((password2[i] <= 'Z' && password2[i] >= 'A')
                || (password2[i] <= 'z' && password2[i] >= 'a')
                || (password2[i] <= '9' && password2[i] >= '0')))
                {
                    Console.WriteLine("Error:密码只能包含字母和数字!");
                    return false;
                }
            }
            //同上判断
            if (password2.Length < 6 || password2.Length > 20)
            {
                Console.WriteLine("Error:the length of password should be 6~20");
                return false;
            }
            //前后密码不匹配
            if (password1 != password2)
            {
                Console.WriteLine("Error:Password not matched!");
                return false;
            }
            string encryptpassword = Encrypt.EncryptString(password1, key);
            UserConfiguration.AddUser(userName, encryptpassword);
            Console.WriteLine("{0} has been created successfully!", userName);
            return true;
        }

        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="commandArg"></param>
        /// <param name="args"></param>
        /// <param name="outFileName"></param>
        /// <param name="grepArg"></param>
        /// <returns>修改密码是否成功</returns>
        public static bool Passwd(String commandArg, List<String> args, String outFileName, List<String> grepArg)
        {
            //判断参数
            if ((!String.IsNullOrEmpty(commandArg)) || (!String.IsNullOrEmpty(outFileName)) || grepArg.Count != 0 || args.Count != 1)
            {
                Console.WriteLine("Error:参数错误!");
                return false;
            }
            string userName = args[0];
            //guest不用密码，不可修改
            if (userName == "guest")
            {
                Console.WriteLine("error: guest need no password!");
                return false;
            }
            User user = UserConfiguration.GetUser(userName);
            //用户不存在
            if (user == null)
            {
                Console.WriteLine("error:user of {0} not exists!", userName);
                return false;
            }
            Console.Write("old password:");
            string oldpassword = GetStandardPassword();
            Console.Write("new password:");
            string password1 = GetStandardPassword();
            Console.Write("new password again:");
            string password2 = GetStandardPassword();
            string password = Encrypt.EncryptString(oldpassword, key);
            //旧密码是否匹配
            if (user.PassWord != password)
            {
                Console.WriteLine("Error:old password not matched!");
                return false;
            }
            //用户密码前后是否匹配
            if (password1 != password2)
            {
                Console.WriteLine("Error:Password not matched!");
                return false;
            }
            else
            {
                //判断密码是否合标准，同上
                for (int i = 0; i < password1.Length; i++)
                {
                    if (!((password1[i] <= 'Z' && password1[i] >= 'A')
                    || (password1[i] <= 'z' && password1[i] >= 'a')
                    || (password1[i] <= '9' && password1[i] >= '0')))
                    {
                        Console.WriteLine("Error:密码只能包含字母和数字!");
                        return false;
                    }
                }
                if (password1.Length < 6 || password1.Length > 20)
                {
                    Console.WriteLine("Error:the length of password should be 6~20");
                    return false;
                }
            }
            string encryptpassword = Encrypt.EncryptString(password1, key);
            UserConfiguration.ChangePassword(userName, encryptpassword);
            Console.WriteLine("{0}'s password has been modified successfully!", userName);
            return true;
        }

        /// <summary>
        /// 切换用户
        /// </summary>
        /// <param name="commandArg"></param>
        /// <param name="args"></param>
        /// <param name="outFileName"></param>
        /// <param name="grepArg"></param>
        /// <returns>切换用户是否成功</returns>
        public static bool SU(String commandArg, List<String> args, String outFileName, List<String> grepArg)
        {
            //判断参数
            if ((!String.IsNullOrEmpty(commandArg)) || (!String.IsNullOrEmpty(outFileName)) || grepArg.Count != 0 || args.Count != 1)
            {
                Console.WriteLine("Error:参数错误!");
                return false;
            }
            string userName = args[0];
            User user = UserConfiguration.GetUser(userName);
            if (userName == Program.CurrentCommand.CurrentUser)
            {
                Console.WriteLine("Error:the same user!");
                return false;
            }
            else
            {
                if (userName == "guest")
                {
                    Console.WriteLine("user changed successfully!");
                    Program.CurrentCommand.CurrentUser = "guest";
                    return true;
                }
                else
                {
                    if (user == null)
                    {
                        Console.WriteLine("Error:user of {0} not exists!", userName);
                        return false;
                    }
                }
            }
            Console.Write("Password:");
            string password = GetStandardPassword();
            string encryptpassword = Encrypt.EncryptString(password, key);
            if (user.PassWord != encryptpassword)
            {
                Console.WriteLine("Error:wrong password!", userName);
                return false;
            }
            else
            {
                ErrorLog.OperationEnd();//operationEnd（）去除的是当前用户的操作，因为logout起到切换用户的特殊性，所以内部就会处理
                Program.CurrentCommand.CurrentUser = userName;
                Console.WriteLine("user changed successfully!");
                return true;
            }
        }

        /// <summary>
        /// 用户登出
        /// </summary>
        /// <param name="commandArg"></param>
        /// <param name="args"></param>
        /// <param name="outFileName"></param>
        /// <param name="grepArg"></param>
        /// <returns>用户是否登出成功</returns>
        public static bool Logout(String commandArg, List<String> args, String outFileName, List<String> grepArg)
        {
            if ((!String.IsNullOrEmpty(commandArg)) || (!String.IsNullOrEmpty(outFileName)) || grepArg.Count != 0 || args.Count != 0)
            {
                Console.WriteLine("Error:参数错误!");
                return false;
            }
            ErrorLog.OperationEnd();//operationEnd（）去除的是当前用户的操作，因为logout起到切换用户的特殊性，所以内部就会处理
            Program.CurrentCommand.CurrentUser = null;
            Program.CurrentCommand.HistoryInput = new string[11];
            Program.CurrentCommand.HistoryInputPointer = 0;     
            return true;
        }


        /// <summary>
        /// 密码输入打印*
        /// </summary>
        /// <returns>接受的密码</returns>
        private static string GetStandardPassword()
        {
            string input = "";
            ConsoleKeyInfo cki = Console.ReadKey(true);
            while (true)
            {
                int count = input.Length;
                if (cki.Key==ConsoleKey.Enter) //按enter输入完毕
                {
                    break;
                }
                else
                {
                    if (cki.Key==ConsoleKey.Backspace)//backspace能够使用
                    {
                        if (count >= 1)
                        {
                            input = input.Substring(0, count - 1);
                            Console.Write("\b \b");
                        }
                    }
                    else
                    {
                        input += cki.KeyChar;
                        Console.Write("*");
                    }
                }
                cki = Console.ReadKey(true);
            }
            Console.WriteLine();
            return input;
        }
    }
}
